<template>
  <div class="tool-box">
    <el-menu
      default-active="0"
      class="el-menu-vertical-demo"
      :collapse="isCollapse"
    >
      <el-menu-item index="1" v-tooltip="'回到初始位置'" @click="flyTo">
        <div class="icon-container">
          <el-icon class="centered-icon"> 复位 </el-icon>
        </div>
      </el-menu-item>
      <el-menu-item index="2" v-tooltip="'面积测量'" @click="measureArea">
        <div class="icon-container">
          <el-icon class="centered-icon">测面积</el-icon>
        </div>
      </el-menu-item>
      <el-menu-item index="3" v-tooltip="'距离测量'" @click="measureDistance">
        <div class="icon-container">
          <el-icon class="centered-icon"> 测距 </el-icon>
        </div>
      </el-menu-item>
      <el-menu-item index="4" v-tooltip="'取消测量'" @click="cancelMeasure">
        <div class="icon-container">
          <el-icon class="centered-icon"> 取消测量 </el-icon>
        </div>
      </el-menu-item>
      <el-menu-item index="5" v-tooltip="'导出图片'" @click="exportImg">
        <div class="icon-container">
          <el-icon class="centered-icon"> 导出 </el-icon>
        </div>
      </el-menu-item>
    </el-menu>
  </div>
</template>

<script lang="ts" setup>
import {
  ref,
  Directive,
  defineProps,
  watch,
  inject,
  defineEmits,
} from 'vue';
import { ElMessage } from 'element-plus';
import * as turf from '@turf/turf'; // 导入 turf 库
import { saveAs } from 'file-saver'; // 导入 file-saver 库

const emit = defineEmits(['toggle-traffic']);
const props = defineProps<{
  map: ol.Map | null;
}>();
const isCollapse = ref(true);

const tooltipDirective: Directive = {
  mounted(el, binding) {
    el.addEventListener('mouseenter', () => {
      const tooltipContent = binding.value;
      const tooltip = document.createElement('div');
      tooltip.className = 'tooltip';
      tooltip.textContent = tooltipContent;
      document.body.appendChild(tooltip);

      const rect = el.getBoundingClientRect();
      tooltip.style.position = 'absolute';
      tooltip.style.left = `${rect.right + window.scrollX}px`;
      tooltip.style.top = `${rect.top + window.scrollY}px`;
      tooltip.style.visibility = 'visible';
      tooltip.style.opacity = '1';
    });

    el.addEventListener('mouseleave', () => {
      const tooltip = document.querySelector('.tooltip');
      if (tooltip) {
        tooltip.remove();
      }
    });
  },
};

const vTooltip = tooltipDirective;

const flyTo = () => {
  if (props.map) {
    const view = props.map.getView();
    const duration = 2000; // 动画持续时间（毫秒）
    const zoom = 14; // 目标缩放级别
    const center = [114.37, 30.495]; // 目标中心坐标

    view.animate({
      center: center,
      zoom: zoom,
      duration: duration,
    });
  } else {
    console.error('Map instance is not available');
  }
};

const exportImg = () => {
  if (props.map) {
    props.map.once('postcompose', function (event) {
      const canvas = event.context.canvas;
      const dataUrl = canvas.toDataURL('image/png');
      const link = document.createElement('a');
      link.download = 'map.png';
      link.href = dataUrl;
      link.click();
    });
    props.map.renderSync();
    ElMessage({
      message: '导出成功!',
      type: 'success',
    });
  } else {
    console.error('Map instance is not available');
  }
};

let draw = null;
let measureLayer = null;
/* 画笔测量 */
const measureArea = () => {
  startMeasure('Polygon');
};

const measureDistance = () => {
  startMeasure('LineString');
};

const cancelMeasure = () => {
  closeMeasure();
};

const startMeasure = (drawType: string) => {
  if (props.map) {
    // 确保在开始新的测量之前移除现有的绘制交互和测量图层
    if (draw) {
      props.map.removeInteraction(draw);
      draw.setActive(false);
    }

    draw = new ol.interaction.Draw({
      source: new ol.source.Vector(),
      type: drawType,
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#a8d2fd',
          lineDash: [5, 5],
          width: 2,
        }),
      }),
    });

    console.log('Adding draw interaction');
    props.map.addInteraction(draw);

    // 创建一个新的矢量图层来显示测量的几何图形
    if (!measureLayer) {
      measureLayer = new ol.layer.Vector({
        source: new ol.source.Vector(),
        style: new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: '#a8d2fd',
            lineDash: [5, 5],
            width: 2,
          }),
        }),
      });
      props.map.addLayer(measureLayer);
    }

    draw.on('drawend', (evt) => {
      const geometry = evt.feature.getGeometry();
      if (drawType == 'LineString') {
        const length = formatLength(geometry);
        ElMessage({
          message: `测量距离: ${length}`,
          type: 'success',
        });
      } else if (drawType =='Polygon') {
        const area = formatArea(geometry);
        ElMessage({
          message: `测量面积: ${area}`,
          type: 'success',
        });
      }
      // 将绘制的几何图形添加到测量图层
      if (measureLayer) {
        measureLayer.getSource().addFeature(evt.feature);
      }
    });
  } else {
    console.error('Map instance is not available');
  }
};

const closeMeasure = () => {
  if (draw) {
    props.map.removeInteraction(draw);
    draw.setActive(false);
  }
  if (measureLayer) {
    measureLayer.getSource().clear();
    props.map.removeLayer(measureLayer);
    measureLayer = null;
  }
};

const formatLength = (line) => {
  const geojsonLine = new ol.format.GeoJSON().writeGeometryObject(line);
  const length = turf.length(geojsonLine, { units: 'meters' });
  return length > 100
    ? `${(length / 1000).toFixed(2)} km`
    : `${length.toFixed(2)} m`;
};

const formatArea = (polygon) => {
  const geojsonPolygon = new ol.format.GeoJSON().writeGeometryObject(polygon);
  const area = turf.area(geojsonPolygon);
  return area > 10000
    ? `${(area / 1000000).toFixed(2)} km²`
    : `${area.toFixed(2)} m²`;
};
</script>

<style>
.tool-box {
  width: 250px;
}

.tooltip {
  background-color: rgb(255, 255, 255);
  color: #000000;
  margin-left: 10px;
  width: 150px;
  height: 30px;
  text-align: center;
  border-radius: 5px;
  padding: 5px;
  position: absolute;
  z-index: 1;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.3s;
}

.el-menu {
  width: 100px;
}

.el-menu-item {
  width: 100px;
}

.icon-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.centered-icon {
  display: block;
}
</style>
